package com.ylyq.ylxx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ylyq.ylxx.constants.AccountConstant;
import com.ylyq.ylxx.context.FilterContextHandler;
import com.ylyq.ylxx.entity.YlyqQuartz;
import com.ylyq.ylxx.model.ResponseData;
import com.ylyq.ylxx.model.bean.OceanenginePlanInfo;
import com.ylyq.ylxx.model.bean.QueryAutoStopOrOpen;
import com.ylyq.ylxx.model.request.*;
import com.ylyq.ylxx.quarz.AutoOpenOrCloseTask;
import com.ylyq.ylxx.quarz.JobServiceImpl;
import com.ylyq.ylxx.service.IOceanegineAutoService;
import com.ylyq.ylxx.service.IOceaneginePlanService;
import com.ylyq.ylxx.service.IYlyqQuartzService;
import com.ylyq.ylxx.util.SnowflakeIdWorkerUtil;
import com.ylyq.ylxx.util.Tools;
import org.apache.commons.lang3.StringUtils;
import org.quartz.JobDataMap;
import org.quartz.SchedulerException;
import org.quartz.TriggerKey;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName OceanegineAutoServiceImpl
 * @Description TODO
 * @Author xiaweichao
 * @Date 2020/7/2 16:28
 * @Version 1.0
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OceanegineAutoServiceImpl implements IOceanegineAutoService {

    @Autowired
    private IYlyqQuartzService ylyqQuartzService;
    @Autowired
    private JobServiceImpl jobService;
    @Autowired
    private IOceaneginePlanService iOceaneginePlanService;

    @Override
    public ResponseData creatAutoStopOrOpen(CreatAutoStopOrOpen creatAutoStopOrOpen) throws SchedulerException {

        String currentDate = Tools.getCurrentDate("yyyy-MM-dd HH:mm:ss");
        String jobGroup = "自动规则监控任务" + currentDate;
        String triggerGroup = "自动规则监控触发器" + currentDate;

        CreatAutoStopOrOpen.ExecutionCondition[] executionConditions = creatAutoStopOrOpen.getExecutionCondition();
        if (executionConditions != null && executionConditions.length > 0) {
            for (CreatAutoStopOrOpen.ExecutionCondition condition : executionConditions) {
                String jobName = jobGroup + SnowflakeIdWorkerUtil.generateId();
                String triggerName = triggerGroup + SnowflakeIdWorkerUtil.generateId();

                YlyqQuartz ylyqQuartz = new YlyqQuartz();
                ylyqQuartz.setAdvertiserId(creatAutoStopOrOpen.getAdvertiser_id());
                ylyqQuartz.setCostCompartType(condition.getCostCompartType());
                ylyqQuartz.setStartNum(condition.getStartNum());
                ylyqQuartz.setCompareCondition(condition.getCompareCondition());
                ylyqQuartz.setDataType(condition.getDataType());
                ylyqQuartz.setEndNum(condition.getEndNum());
                ylyqQuartz.setRate(condition.getRate());
                ylyqQuartz.setDayNum(condition.getDayNum());
                ylyqQuartz.setMoney(creatAutoStopOrOpen.getMoney());
                ylyqQuartz.setOperating(creatAutoStopOrOpen.getOperating());
                ylyqQuartz.setPlans(Arrays.toString(creatAutoStopOrOpen.getPlans()).replace("[", "").replace("]", ""));

                ylyqQuartz.setJobGroup(jobGroup);
                ylyqQuartz.setJobName(jobName);
                ylyqQuartz.setTirggerName(triggerName);
                ylyqQuartz.setTriggerGroup(triggerGroup);
                ylyqQuartz.setType(creatAutoStopOrOpen.getExecutionTime().getType());
                ylyqQuartz.setTime(creatAutoStopOrOpen.getExecutionTime().getTime());
                boolean save = ylyqQuartzService.save(ylyqQuartz);
                if (save) {
                    //每隔5秒执行一次：*/5 * * * * ?
                    //
                    //每隔10分钟执行一次：0 */10 * * * ?
                    //
                    //每天23点执行一次：0 0 23 * * ?
                    //
                    //每天凌晨1点执行一次：0 0 1 * * ?
                    //
                    //每月1号凌晨1点执行一次：0 0 1 1 * ?
                    //
                    //每月最后一天23点执行一次：0 0 23 L * ?
                    //
                    //每周星期天凌晨1点实行一次：0 0 1 ? * L
                    //
                    //在26分、29分、33分执行一次：0 26,29,33 * * * ?
                    //
                    //每天的0点、13点、18点、21点都执行一次：0 0 0,13,18,21 * * ?
                    String time = null;
                    if (creatAutoStopOrOpen.getExecutionTime().getType() == 0) {//执行频率方式。0：每多少分钟执行一次，不得少于10分钟。1：每天几点定时执行
                        time = "0 */" + creatAutoStopOrOpen.getExecutionTime().getTime() + " * * * ?";
                    } else if (creatAutoStopOrOpen.getExecutionTime().getType() == 3) {
                        time = "0 0 */" + creatAutoStopOrOpen.getExecutionTime().getTime() + " * * ?";
                    } else if (creatAutoStopOrOpen.getExecutionTime().getType() == 1) {
                        time = "0 0 " + creatAutoStopOrOpen.getExecutionTime().getTime() + " * * ?";
                    } else if (creatAutoStopOrOpen.getExecutionTime().getType() == 2) {
                        time = Tools.formatDateByPattern(creatAutoStopOrOpen.getExecutionTime().getTime());
                    }
                    JobDataMap jobDataMap = new JobDataMap();
                    jobDataMap.put("userID", FilterContextHandler.getUserID());
                    jobDataMap.put("advertiserId", creatAutoStopOrOpen.getAdvertiser_id());
                    jobService.addJob(jobName, jobGroup, triggerName,
                            triggerGroup, jobDataMap, AutoOpenOrCloseTask.class, time);
                }
            }
        }

        return new ResponseData(ResponseData.Result.SUCCESS);

//        try {
//            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
//            Scheduler scheduler = schedulerFactory.getScheduler();
//            // 启动scheduler
//            scheduler.start();
//            // 创建HelloworldJob的JobDetail实例，并设置name/group
//            JobDetail jobDetail = JobBuilder.newJob(UploadTask.class)
//                    .withIdentity("myJob","myJobGroup1")
//                    //JobDataMap可以给任务传递参数
//                    .usingJobData("job_param","job_param1")
//                    .build();
//            // 创建Trigger触发器设置使用cronSchedule方式调度
//            Trigger trigger = TriggerBuilder.newTrigger()
//                    .withIdentity("myTrigger","myTriggerGroup1")
//                    .usingJobData("job_trigger_param","job_trigger_param1")
//                    .startNow()
//                    //.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
//                    .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ? 2018"))
//                    .build();
//            // 注册JobDetail实例到scheduler以及使用对应的Trigger触发时机
//            scheduler.scheduleJob(jobDetail,trigger);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
    }

    @Override
    public ResponseData updateAutoStopOrOpen(UpdateAutoStopOrOpen updateAutoStopOrOpen) throws SchedulerException {
        UpdateAutoStopOrOpen.ExecutionCondition[] executionConditions = updateAutoStopOrOpen.getExecutionCondition();
        if (executionConditions != null && executionConditions.length > 0) {
            for (UpdateAutoStopOrOpen.ExecutionCondition condition : executionConditions) {
                QueryWrapper<YlyqQuartz> ylyqQuartzQueryWrapper=new QueryWrapper<>();
                ylyqQuartzQueryWrapper.eq("job_group",updateAutoStopOrOpen.getJobGroup());
                ylyqQuartzQueryWrapper.eq("job_name",condition.getJobName());
                ylyqQuartzQueryWrapper.eq("trigger_group",updateAutoStopOrOpen.getTriggerGroup());
                ylyqQuartzQueryWrapper.eq("tirgger_name",condition.getTirggerName());
                ylyqQuartzQueryWrapper.eq("advertiser_id",updateAutoStopOrOpen.getAdvertiser_id());

                YlyqQuartz ylyqQuartz = new YlyqQuartz();
                ylyqQuartz.setAdvertiserId(updateAutoStopOrOpen.getAdvertiser_id());
                ylyqQuartz.setCostCompartType(condition.getCostCompartType());
                ylyqQuartz.setStartNum(condition.getStartNum());
                ylyqQuartz.setCompareCondition(condition.getCompareCondition());
                ylyqQuartz.setDataType(condition.getDataType());
                ylyqQuartz.setEndNum(condition.getEndNum());
                ylyqQuartz.setRate(condition.getRate());
                ylyqQuartz.setDayNum(condition.getDayNum());
                ylyqQuartz.setMoney(updateAutoStopOrOpen.getMoney());
                ylyqQuartz.setOperating(updateAutoStopOrOpen.getOperating());
                ylyqQuartz.setPlans(Arrays.toString(updateAutoStopOrOpen.getPlans()).replace("[", "").replace("]", ""));
                boolean update = ylyqQuartzService.update(ylyqQuartz, ylyqQuartzQueryWrapper);
                if (update) {
                    String time = null;
                    if (updateAutoStopOrOpen.getExecutionTime().getType() == 0) {//执行频率方式。0：每多少分钟执行一次，不得少于10分钟。1：每天几点定时执行
                        time = "0 */" + updateAutoStopOrOpen.getExecutionTime().getTime() + " * * * ?";
                    } else if (updateAutoStopOrOpen.getExecutionTime().getType() == 3) {
                        time = "0 0 */" + updateAutoStopOrOpen.getExecutionTime().getTime() + " * * ?";
                    } else if (updateAutoStopOrOpen.getExecutionTime().getType() == 1) {
                        time = "0 0 " + updateAutoStopOrOpen.getExecutionTime().getTime() + " * * ?";
                    } else if (updateAutoStopOrOpen.getExecutionTime().getType() == 2) {
                        time = Tools.formatDateByPattern(updateAutoStopOrOpen.getExecutionTime().getTime());
                    }
                    JobDataMap jobDataMap = new JobDataMap();
                    jobDataMap.put("userID", FilterContextHandler.getUserID());
                    jobDataMap.put("advertiserId", updateAutoStopOrOpen.getAdvertiser_id());

                    jobService.updateJob(new TriggerKey(condition.getTirggerName(),updateAutoStopOrOpen.getJobGroup()),time);
                }
            }
        }

        return new ResponseData(ResponseData.Result.SUCCESS);
    }

    @Override
    public ResponseData queryStopOrOpen(QueryAutoStopOrOpenRequest queryAutoStopOrOpenRequest) {

        QueryAutoStopOrOpen queryAutoStopOrOpen = new QueryAutoStopOrOpen();
        queryAutoStopOrOpen.setAdvertiserId(queryAutoStopOrOpenRequest.getAdvertiser_id());

        QueryWrapper<YlyqQuartz> queryWrapper = new QueryWrapper<>();
//        queryWrapper.inSql("job_group","select t.job_group from (SELECT job_group FROM `ylyq_quartz`" +
//                "WHERE advertiser_id="+queryAutoStopOrOpenRequest.getAdvertiser_id()+" GROUP BY job_group LIMIT "+
//                (queryAutoStopOrOpenRequest.getPage()-1)*queryAutoStopOrOpenRequest.getPageSize()+","+queryAutoStopOrOpenRequest.getPageSize()+")as t");
//
//        List<YlyqQuartz> listQuartzs = ylyqQuartzService.list(queryWrapper);

        queryWrapper.select("job_group", "trigger_group", "plans","type","time","money");
        queryWrapper.eq("advertiser_id", queryAutoStopOrOpenRequest.getAdvertiser_id());
        if (StringUtils.isNotBlank(queryAutoStopOrOpenRequest.getJobName())) {
            queryWrapper.eq("job_name", queryAutoStopOrOpenRequest.getJobName());
        }
        queryWrapper.groupBy("job_group");
        queryWrapper.orderByDesc("updated_time");

        IPage<YlyqQuartz> page = ylyqQuartzService.page(new Page<>(queryAutoStopOrOpenRequest.getPage() == null ? 1 : queryAutoStopOrOpenRequest.getPage(),
                queryAutoStopOrOpenRequest.getPageSize() == null ? 10 : queryAutoStopOrOpenRequest.getPageSize()), queryWrapper);

        queryAutoStopOrOpen.setPageSize(page.getSize());
        queryAutoStopOrOpen.setPage(page.getPages());
        queryAutoStopOrOpen.setCurrent(page.getCurrent());
        queryAutoStopOrOpen.setTotal(page.getTotal());

        List<YlyqQuartz> ylyqQuartzs = page.getRecords();
        List<QueryAutoStopOrOpen.QueryAutoStopOrOpenList> detailList = new ArrayList<>();
        for (YlyqQuartz temp : ylyqQuartzs) {
            QueryAutoStopOrOpen.QueryAutoStopOrOpenList detail = new QueryAutoStopOrOpen.QueryAutoStopOrOpenList();
            //获取计划名称
            GetPlanInfoRequest getPlanInfoRequest = new GetPlanInfoRequest();
            getPlanInfoRequest.setAdvertiser_id(queryAutoStopOrOpenRequest.getAdvertiser_id());
            getPlanInfoRequest.setPage_size(temp.getPlans().split(",").length);
            GetPlanInfoRequest.FilteringGetPlanInfoRequest filteringGetPlanInfoRequest = new GetPlanInfoRequest.FilteringGetPlanInfoRequest();
            filteringGetPlanInfoRequest.setIds(Tools.StringArray2LongArray(temp.getPlans().split(",")));
            getPlanInfoRequest.setFiltering(filteringGetPlanInfoRequest);
            OceanenginePlanInfo oceanenginePlanInfo = iOceaneginePlanService.getPlan(getPlanInfoRequest);
            if (oceanenginePlanInfo.getCode() == AccountConstant.SUCCESS) {
                List<QueryAutoStopOrOpen.QueryAutoStopOrOpenList.QueryAutoStopOrOpenPlanList> queryAutoStopOrOpenPlanListList=new ArrayList<>();
                List<OceanenginePlanInfo.DataBean.ListBean> listPlans = oceanenginePlanInfo.getData().getList();
                for (OceanenginePlanInfo.DataBean.ListBean tempPlan:listPlans) {
                    QueryAutoStopOrOpen.QueryAutoStopOrOpenList.QueryAutoStopOrOpenPlanList queryAutoStopOrOpenPlan=new QueryAutoStopOrOpen.QueryAutoStopOrOpenList.QueryAutoStopOrOpenPlanList();
                    BeanUtils.copyProperties(tempPlan,queryAutoStopOrOpenPlan);
                    queryAutoStopOrOpenPlanListList.add(queryAutoStopOrOpenPlan);
                }
                detail.setPlanNames(queryAutoStopOrOpenPlanListList);
            }

            detail.setJobGroup(temp.getJobGroup());
            detail.setTriggerGroup(temp.getTriggerGroup());
            detail.setType(temp.getType());
            detail.setMoney(temp.getMoney());

            QueryWrapper<YlyqQuartz> queryWrapperDetail = new QueryWrapper<>();
            queryWrapperDetail.select("dataType", "day_num", "compare_condition", "cost_compart_type", "start_num", "end_num", "rate", "operating","job_name","tirgger_name");
            queryWrapperDetail.eq("job_group", temp.getJobGroup());
            List<Map<String, Object>> maps = ylyqQuartzService.listMaps(queryWrapperDetail);
            detail.setCollet(maps);

            detailList.add(detail);
        }
        queryAutoStopOrOpen.setDetailList(detailList);

        return new ResponseData(ResponseData.Result.SUCCESS, queryAutoStopOrOpen);
    }

    @Override
    public ResponseData deleteAutoStopOrOpen(DeleteAutoStopOrOpenRequest deleteAutoStopOrOpenRequest) throws SchedulerException {
        QueryWrapper<YlyqQuartz> quartzQueryWrapper = new QueryWrapper<>();
        quartzQueryWrapper.eq("advertiser_id", deleteAutoStopOrOpenRequest.getAdvertiser_id());
        quartzQueryWrapper.eq("job_group", deleteAutoStopOrOpenRequest.getJobGroup());
//        quartzQueryWrapper.eq("job_name", deleteAutoStopOrOpenRequest.getJobName());
        quartzQueryWrapper.eq("trigger_group", deleteAutoStopOrOpenRequest.getTriggerGroup());
//        quartzQueryWrapper.eq("tirgger_name", deleteAutoStopOrOpenRequest.getTirggerName());
        ylyqQuartzService.remove(quartzQueryWrapper);

//            JobDataMap jobDataMap = new JobDataMap();
//            jobDataMap.put("creatAutoStopOrOpen", loginDTO);
//            jobService.addJob("Job_Auto"+new Date().toString(),"JobAutoOpenOrClose","Trigger_Auto"+new Date().toString(),
//                    "TiggerAutoOpenOrClose",jobDataMap, TestTask.class,"0/3 * * * * ? ");
//            jobService.deleteJob(triggerName, triggerGroup, jobName, jobGroup);

//        jobService.deleteJob(deleteAutoStopOrOpenRequest.getTirggerName(), deleteAutoStopOrOpenRequest.getTriggerGroup(), deleteAutoStopOrOpenRequest.getJobName(), deleteAutoStopOrOpenRequest.getJobGroup());
        jobService.deleteJobByGroup(deleteAutoStopOrOpenRequest.getJobGroup(),deleteAutoStopOrOpenRequest.getTriggerGroup());
        return new ResponseData(ResponseData.Result.SUCCESS);
    }

}
